package app

import (
	"fmt"
	"os"
	"path/filepath"
	"time"

	"github.com/go-apibox/api"
	"github.com/go-apibox/filter"
	"github.com/go-apibox/utils"
	"github.com/tealeg/xlsx"
)

func ActionTaskGroupList(c *api.Context) interface{} {
	params := c.NewParams()
	params.AddPagination().AddOrderBy("CreateTime", "desc", []string{"CreateTime"}, false)
	params.Add("DeviceGroupId", filter.EmptyToNil(), filter.Uint32())
	params.Add("DeviceGroupName", filter.EmptyToNil(), filter.String())

	params.Add("Name", filter.EmptyToNil(), filter.String())
	params.Add("Desc", filter.EmptyToNil(), filter.String())
	params.Add("Status", filter.EmptyToNil(), filter.String())
	if apiErr := params.Parse(); apiErr != nil {
		return apiErr
	}

	list := make([]*TaskGroup, 0, 10)
	return api.List(c, &list, params, nil)
}

func ActionTaskGroupCreate(c *api.Context) interface{} {
	params := c.NewParams()
	params.Add("DeviceGroupId", filter.EmptyToNil(), filter.Required(), filter.Uint32())
	params.Add("ProductPath", filter.EmptyToNil(), filter.Required(), filter.String())
	params.Add("HoldSec", filter.EmptyToNil(), filter.Int(), filter.Default(10))
	params.Add("Retry", filter.EmptyToNil(), filter.Int(), filter.Default(3))
	params.Add("AppointmentTime", filter.EmptyToNil(), filter.Int64())
	params.Add("StopTime", filter.EmptyToNil(), filter.Int64())

	params.Add("Name", filter.EmptyToNil(), filter.String())
	params.Add("Desc", filter.EmptyToNil(), filter.String())
	if apiErr := params.Parse(); apiErr != nil {
		return apiErr
	}

	// 查询分组是否存证
	dgId := params.GetUint32("DeviceGroupId")
	dg := new(DeviceGroup)
	has, err := app.engine.Where("device_group_id=?", dgId).Get(dg)
	if err != nil {
		app.logger.Error(err)
		return c.Error.New(api.ErrorInvalidParam, "DeviceGroupId")
	}
	if !has {
		return c.Error.New(api.ErrorInvalidParam, "DeviceGroupId")
	}

	path := filepath.Join(app.config.DataDir, params.GetString("ProductPath"))
	if _, err := os.Stat(path); err != nil {
		app.logger.Error(err)
		return c.Error.New(api.ErrorInvalidParam, "ProductPath")
	}

	aTime := params.GetInt64("AppointmentTime")
	sTime := params.GetInt64("StopTime")
	now := time.Now()
	if aTime == 0 || aTime < now.Unix() {
		// 第二天凌晨开始
		tmp := 24 - now.Hour()
		tmp = tmp*3600 - now.Minute()*60
		aTime = now.Unix() + int64(tmp)
		params.Set("AppointmentTime", aTime)
	}
	if sTime == 0 || sTime < now.Unix() {
		sTime = aTime + 86400
		params.Set("StopTime", sTime)
	}

	xfile, err := xlsx.OpenFile(path)
	if err != nil {
		app.logger.Error(err)
		return c.Error.New(api.ErrorInvalidParam, "ProductPath")
	}

	taskGroupId := utils.RandUint32()
	holdSec := params.GetInt("HoldSec")
	retry := params.GetInt("Retry")
	params.Set("TaskGroupId", taskGroupId)

	taskLogs := make([]*TaskLog, 0, 100)
	for _, sheet := range xfile.Sheet {
		if len(sheet.Rows) < 2 {
			continue
		}
		for _, row := range sheet.Rows[2:] {
			if len(row.Cells[0].String()) == 0 {
				break
			}

			tmp := &TaskLog{
				// TaskLogId:   utils.RandUint64(),
				TaskGroupId: taskGroupId,

				DeviceGroupId:   dg.DeviceGroupId,
				DeviceGroupName: dg.DeviceGroupName,

				Status: TASK_STATUS_UNDO,

				Account:      row.Cells[0].String(),
				ProductCode:  row.Cells[1].String(),
				ProductTitle: row.Cells[2].String(),
				IsStart:      row.Cells[3].String(),
				ReleaseTime:  row.Cells[4].String(),
				Addr:         fmt.Sprintf("https://market.m.taobao.com/app/tb-source-app/video-fullpage/pages/index2?wh_weex=false&wx_navbar_hidden=true&wx_navbar_transparent=true&type=guangguang&source=guangguang&id=%s", row.Cells[1].String()),
				HoldSec:      holdSec,
				Retry:        retry,

				AppointmentTime: aTime,
				StopTime:        sTime,

				CreateTime: uint32(now.Unix()),
			}

			taskLogs = append(taskLogs, tmp)
		}
	}

	devices := make([]*Device, 0, 100)
	if err = app.engine.Where("device_group_id=?", dgId).Find(&devices); err != nil {
		app.logger.Error(err)
		return c.Error.New(api.ErrorInvalidParam, "connect db faield")
	}
	for _, d := range devices {
		for _, tl := range taskLogs {
			tl.TaskLogId = utils.RandUint64()
			tl.DeviceId = d.DeviceId
			tl.DeviceCode = d.Code
			tl.DeviceName = d.Name
		}

		if _, err = app.engine.Insert(taskLogs); err != nil {
			app.logger.Error(err)
		}

	}

	task := new(TaskGroup)
	data := api.Create(c, task, params)
	return data
	if !api.IsError(data) {
		// xx
	}
	return data
}

func ActionTaskGroupDetail(c *api.Context) interface{} {
	params := c.NewParams()
	params.Add("TaskGroupId", filter.EmptyToNil(), filter.Required(), filter.Uint32())
	if apiErr := params.Parse(); apiErr != nil {
		return apiErr
	}
	return api.Detail(c, new(TaskGroup), params)
}

func ActionTaskGroupDelete(c *api.Context) interface{} {
	params := c.NewParams()
	params.Add("TaskGroupId", filter.EmptyToNil(), filter.Required(), filter.Uint32())
	if apiErr := params.Parse(); apiErr != nil {
		return apiErr
	}

	return api.Delete(c, new(TaskGroup), params)
}
